package comp.wxapi.service;
import comp.wxapi.vo.*;

import comp.wxapi.entity.*;

import org.springframework.data.domain.Page;

import java.util.*;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.config.WxPayConfig;

import cn.binarywang.wx.miniapp.api.WxMaMsgService;
import cn.binarywang.wx.miniapp.api.WxMaTemplateService;
import cn.binarywang.wx.miniapp.api.WxMaUserService;
import cn.binarywang.wx.miniapp.api.impl.WxMaMsgServiceImpl;
import cn.binarywang.wx.miniapp.api.impl.WxMaTemplateServiceImpl;
import cn.binarywang.wx.miniapp.api.impl.WxMaUserServiceImpl;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult;
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
import comp.wxapi.bean.BaseConfigBean;
import comp.wxapi.bean.LogoConfig;
import comp.wxapi.bean.MiniQrcode;
import comp.wxapi.bean.Result;
import comp.wxapi.constants.Constants;
import comp.wxapi.utils.QrcodeUtils;
import comp.wxapi.utils.RequestUtils;
import comp.wxapi.utils.UUIDUtils;
import comp.wxapi.vo.MaterialVo;
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import okhttp3.ResponseBody;
import weixin.popular.api.QrcodeAPI;
import weixin.popular.api.WxaAPI;
import weixin.popular.bean.BaseResult;
import weixin.popular.bean.qrcode.Wxaqrcode;
import weixin.popular.bean.wxa.Addnearbypoi;
import weixin.popular.bean.wxa.AddnearbypoiResult;
import weixin.popular.bean.wxa.GetnearbypoilistPoi;
import weixin.popular.bean.wxa.GetnearbypoilistResult;
import weixin.popular.bean.wxa.Getwxacode;
import weixin.popular.bean.wxa.Getwxacodeunlimit;
import weixin.popular.bean.wxa.LineColor;


@Service
public class MiniappUserService extends MiniappService {
	
	public static final String SESSION_URL = "/session";
	
	@Autowired
	private EventService eventService;
	@Autowired
	private CardService cardService;
	@Autowired
	private PayService payService;
	@Autowired
	private MaterialService materialService;

	/**
	 * 小程序sessiok_key等信息获取
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public String jscode2session(String code) throws Exception{
		BaseConfigBean configBean = getBaseConfig("");
		//获取sessionKey信息
		WxMaUserService wxMaUserService = new WxMaUserServiceImpl(wxMaService(configBean));
		WxMaJscode2SessionResult sessionInfo = wxMaUserService.getSessionInfo(code);
//		String cookie = getCookie();
//		RequestUtils.setSession(host()+SESSION_URL, cookie, "openid", sessionInfo.getOpenid());
//		Response response = RequestUtils.setSession(host()+SESSION_URL, cookie, "sessionKey", sessionInfo.getSessionKey());
//		if(StringUtils.isNotEmpty(sessionInfo.getUnionid())) {
//			RequestUtils.setSession(host()+SESSION_URL, cookie, "unionid", sessionInfo.getUnionid());
//		}
//		String resCookie = RequestUtils.getCookie(response);
//		HttpServletResponse httpServletResponse = getResponse();
//		httpServletResponse.setHeader(org.springframework.http.HttpHeaders.SET_COOKIE, resCookie);
		return JSON.toJSONString(Result.ok(sessionInfo));
	}
	
	/**
	 * 解密获取用户绑定在微信上的电话号码
	 * @param encryptedData
	 * @param iv
	 * @return
	 * @throws Exception
	 */
	public String getPhoneNumber(String encryptedData, String iv) throws Exception{
		BaseConfigBean configBean = getBaseConfig("");
		encryptedData = urlDecode(encryptedData);
		iv = urlDecode(iv);
		WxMaUserService wxMaUserService = new WxMaUserServiceImpl(wxMaService(configBean));
		WxMaPhoneNumberInfo phoneNumberInfo = wxMaUserService.getPhoneNoInfo(configBean.getSessionKey(),
				encryptedData, iv);
		return JSON.toJSONString(Result.ok(phoneNumberInfo));
	}
	
	/**
	 * 解密获取小程序用户信息
	 * @param encryptedData
	 * @param iv
	 * @return
	 * @throws Exception
	 */
	public String miniappUserInfo(String encryptedData, String iv) throws Exception{
		BaseConfigBean configBean = getBaseConfig("");
		logger.info("=====sessionKey:{}" , configBean.getSessionKey());
		logger.info("=====encryptedData:{}" ,encryptedData);
		logger.info("=====ivStr:{}", iv);
		String userInfo = WxMaCryptUtils.decrypt(configBean.getSessionKey(), encryptedData, iv);
		return JSON.toJSONString(Result.ok(userInfo));
	}
	
	public static String urlDecode(String str) {
		try {
			str = URLDecoder.decode(str, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			logger.error("【url decode fail】",e);
		}
		return str;
	}
	
	/**
	 * 小程序二维码
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String createwxaqrcode(String data) throws Exception{
		String qrcode = getQrcode(JSON.parseObject(data, MiniQrcode.class), "wxaqrcode");
		return JSON.toJSONString(Result.ok(qrcode));
	}

	/**
	 * 小程序码（有限）
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String getwxacode(String data) throws Exception{
		String qrcode = getQrcode(JSON.parseObject(data, MiniQrcode.class), "wxacode");
		return JSON.toJSONString(Result.ok(qrcode));
	}

	/**
	 * 小程序码（数量无限）
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String getwxacodeunlimit(String data) throws Exception{
		String qrcode = getQrcode(JSON.parseObject(data, MiniQrcode.class), "wxacodeunlimit");
		return JSON.toJSONString(Result.ok(qrcode));
	}
	
	public String getQrcode(MiniQrcode miniQrcode, String type) throws WxErrorException {
		String bString = "";
		BaseConfigBean configBean = getBaseConfig(miniQrcode.getGroup());
		String accessToken = getAccessToken(configBean.getAppid(), configBean.getAppsecret());
		BufferedImage image = null;
		//调用微信接口，生成小程序码或者小程序二维码
		
		
		if ("wxacode".equals(type)) {//小程序码（有限）
			LineColor lineColor = miniQrcode.getLine_color();
			
			image = WxaAPI.getwxacode(accessToken, new Getwxacode(miniQrcode.getPath(), miniQrcode.getWidth(), miniQrcode.isAuto_color(), lineColor));
		} else if ("wxacodeunlimit".equals(type)) {//小程序码（无限）
			LineColor lineColor = miniQrcode.getLine_color();
			Getwxacodeunlimit getwxacodeunlimit = new Getwxacodeunlimit(miniQrcode.getScene(), miniQrcode.getWidth(), miniQrcode.isAuto_color(), lineColor);
			getwxacodeunlimit.setPage(miniQrcode.getPage());
			image = WxaAPI.getwxacodeunlimit(accessToken, getwxacodeunlimit);
		} else if ("wxaqrcode".equals(type)) {//小程序二维码（有限）
			image = QrcodeAPI.wxaappCreatewxaqrcode(accessToken, new Wxaqrcode(miniQrcode.getPath(), miniQrcode.getWidth()));
		}
		FileInputStream inputStream = null;
		//小程序二维码或者小程序码中间写入logo
		try {
			File output = new File(new File("").getCanonicalFile()+File.separator+UUIDUtils.lowerCaseUUID()+"."+QrcodeUtils.DEFAULT_FORMAT);	
			//传入logo则写入
			if(StringUtils.isNotEmpty(miniQrcode.getLogoUrl())) {
				LogoConfig logoConfig = new LogoConfig(Color.WHITE, 3);
				QrcodeUtils.writeLogoIntoQrcode(image, getLogoFile(miniQrcode.getLogoUrl()), logoConfig,output);
			}else {//否则不写入
				ImageIO.write(image, QrcodeUtils.DEFAULT_FORMAT, output);
			}
			inputStream = new FileInputStream(output);
			bString = "data:image/png;base64,"+Base64.encodeBase64String(IOUtils.toByteArray(inputStream));
			FileUtils.deleteQuietly(output);
		} catch (Exception e) {
			logger.error("ERROR:", e);
			throw new RuntimeException("获取小程序码失败！",e);
		}finally {
			IOUtils.closeQuietly(inputStream);
		}
		return bString;
	}
	
	
	public FileInputStream qrcode(MiniQrcode miniQrcode, String type) throws WxErrorException {
		BaseConfigBean configBean = getBaseConfig(miniQrcode.getGroup());
		String accessToken = getAccessToken(configBean.getAppid(), configBean.getAppsecret());
		BufferedImage image = null;
		//调用微信接口，生成小程序码或者小程序二维码
		if ("wxacode".equals(type)) {//小程序码（有限）
			LineColor lineColor = miniQrcode.getLine_color();
			image = WxaAPI.getwxacode(accessToken, new Getwxacode(miniQrcode.getPath(), miniQrcode.getWidth(), miniQrcode.isAuto_color(), lineColor));
		} else if ("wxacodeunlimit".equals(type)) {//小程序码（无限）
			LineColor lineColor = miniQrcode.getLine_color();
			image = WxaAPI.getwxacodeunlimit(accessToken, new Getwxacodeunlimit(miniQrcode.getScene(), miniQrcode.getWidth(), miniQrcode.isAuto_color(), lineColor));
		} else if ("wxaqrcode".equals(type)) {//小程序二维码（有限）
			image = QrcodeAPI.wxaappCreatewxaqrcode(accessToken, new Wxaqrcode(miniQrcode.getPath(), miniQrcode.getWidth()));
		}
		FileInputStream inputStream = null;
		//小程序二维码或者小程序码中间写入logo
		try {
			File output = new File(new File("").getCanonicalFile()+File.separator+UUIDUtils.lowerCaseUUID()+"."+QrcodeUtils.DEFAULT_FORMAT);	
			//传入logo则写入
			if(StringUtils.isNotEmpty(miniQrcode.getLogoUrl())) {
				LogoConfig logoConfig = new LogoConfig(Color.WHITE, 3);
				QrcodeUtils.writeLogoIntoQrcode(image, getLogoFile(miniQrcode.getLogoUrl()), logoConfig,output);
			}else {//否则不写入
				ImageIO.write(image, QrcodeUtils.DEFAULT_FORMAT, output);
			}
			inputStream = new FileInputStream(output);
		} catch (Exception e) {
			logger.error("ERROR:", e);
		}finally {
			IOUtils.closeQuietly(inputStream);
		}
		return inputStream;
	}
	
	/**
	 * 读取logo文件输入流
	 * @param minioUrl
	 * @return
	 */
	private InputStream getLogoFile(String minioUrl) {
		ResponseBody body = RequestUtils.get(minioUrl, null);
		return body.byteStream();
	}
	
	/**
	 * 小程序模板消息发送
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String templateSend(String data) throws Exception{
		WxMaTemplateMessage wxMaTemplateMessage = JSON.parseObject(data, WxMaTemplateMessage.class);
		//必须参数校验
		if(StringUtils.isEmpty(wxMaTemplateMessage.getFormId())) {
			return JSONObject.toJSONString(Result.error("invalid formId"));
		}
		BaseConfigBean configBean = getBaseConfig("");
		if(StringUtils.isEmpty(wxMaTemplateMessage.getToUser()) && StringUtils.isEmpty(configBean.getOpenid())) {
			return JSON.toJSONString(Result.error("用户标识OpenID必须！"));
		}else {
			//通过userId获取用户的openId
			//http://localhost:8080/uaa/Users?filterShadowUser=false&filter=real+eq+“1dfa3f38-29c8-4432-ac0f-86c937ffe630“+and+data2+eq+“miniapp“
			if(StringUtils.isNotEmpty(wxMaTemplateMessage.getToUser())) {
				String userId = wxMaTemplateMessage.getToUser();
				Map<String,String> param = new HashMap<>();
				param.put("filterShadowUser", "false");
				param.put("filter", "real eq \""+userId+"\" and data2 eq \"miniapp\"");
				String url = host()+"/uaa/Users";
				String secret = getHeader("X-APP-SECRET");
				logger.info("【secret={}】",secret);
				String res = RequestUtils.getUaaUser(url, param,secret).string();
				logger.info("【uaa user info】\n{}",res);
				JSONObject json = JSONObject.parseObject(res);
				String resources = json.getString("resources");
				if(!"[]".equals(resources)) {
					json = JSONObject.parseArray(resources, JSONObject.class).get(0);
					String openId = json.getString("userName");
					wxMaTemplateMessage.setToUser(openId);
				}else {
					param.put("filter", "real eq \""+userId+"\"");
					res = RequestUtils.getUaaUser(url, param,secret).string();
					logger.info("【uaa user info】\n{}",res);
					json = JSONObject.parseObject(res);
					resources = json.getString("resources");
					if(!"[]".equals(resources)) {
						json = JSONObject.parseArray(resources, JSONObject.class).get(0);
						String openId = json.getString("userName");
						wxMaTemplateMessage.setToUser(openId);
					}else {
						wxMaTemplateMessage.setToUser(configBean.getOpenid());
					}
				}
			}else {
				wxMaTemplateMessage.setToUser(configBean.getOpenid());
			}
		}
		
		WxMaMsgService wxMaMsgService = new WxMaMsgServiceImpl(wxMaService(configBean));
		wxMaMsgService.sendTemplateMsg(wxMaTemplateMessage);
		return JSON.toJSONString(Result.ok());
	}

	/**
	 * 小程序模板消息列表
	 * @param pageNum
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	public String templateList(Integer pageNum, Integer pageSize, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		WxMaTemplateService wxMaTemplateService = new WxMaTemplateServiceImpl(wxMaService(configBean));
		WxMaTemplateListResult templateList = wxMaTemplateService.findTemplateList((pageNum-1)*pageSize, pageSize);
		Result<?> result = Result.ok(templateList.getList());
		return JSON.toJSONString(result);
	}

	/**
	 * 小程序模板消息删除
	 * @param templateId
	 * @return
	 * @throws Exception
	 */
	public String templateDel(String templateId, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		WxMaTemplateService wxMaTemplateService = new WxMaTemplateServiceImpl(wxMaService(configBean));
		wxMaTemplateService.delTemplate(templateId);
		return JSON.toJSONString(Result.ok());
	}
	
	/**
	 * 微信消息推送事件
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String wxeventPost(String data) throws Exception{
		BaseConfigBean baseConfigBean = getRequestParams();
		Long start = System.currentTimeMillis();
		//签名校验，校验请求是否来自微信服务器
		if(!baseConfigBean.isWxOffical()) {
			
			return "非法请求";
		}
		String result = eventService.eventService(baseConfigBean, data);
		Long end = System.currentTimeMillis();
		logger.info("【请求时间】:{}ms",end-start);
		return result;
	}

	public String wxeventGet() throws Exception{
		BaseConfigBean configBean = getRequestParams();
		String result = "";
		if(!configBean.isWxOffical()) {
			return "非法请求";
		}
		
		if(StringUtils.isNotBlank(configBean.getEchostr())) {
			result = configBean.getEchostr();
		}
		return result;
	}
	
	/**
	 * 事件请求参数获取
	 * @param request
	 * @return
	 */
	public BaseConfigBean getRequestParams() {
		HttpServletRequest request = getRequest();
		BaseConfigBean baseConfigBean = getBaseConfig();
		baseConfigBean.setEchostr(request.getParameter("echostr"));
		baseConfigBean.setEncrypt_type(request.getParameter("encrypt_type"));
		baseConfigBean.setMsg_signature(request.getParameter("msg_signature"));
		baseConfigBean.setNonce(request.getParameter("nonce"));
		baseConfigBean.setSignature(request.getParameter("signature"));
		baseConfigBean.setTimestamp(request.getParameter("timestamp"));
		logger.info("微信推送事件请求参数===============baseConfigBean===============\n{}",JSON.toJSONString(baseConfigBean));
		return baseConfigBean;
	}
	
	/**
	 * 卡券创建
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String createCard(String data) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		Result<?> result = cardService.cardCreate(data, getAccessToken(configBean.getAppid(), configBean.getAppsecret()));
		return JSON.toJSONString(result);
	}

	/**
	 * 卡券签名
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public String createSignature(String data) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		WxCardApiSignature wxCardApiSignature = cardService.signature(data, configBean);
		return JSON.toJSONString(Result.ok(wxCardApiSignature));
	}

	public String consumeCard(String data) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		return cardService.consumeCard(data, configBean);
	}

	public String decryptCode(String encryptCode) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		String reString = cardService.decryptCode(encryptCode, configBean);
		return JSON.toJSONString(Result.ok(reString));
	}

	public String cardCodeQuery(String code, String cardId) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		Result<?> result = cardService.queryCardCode(cardId, code, configBean);
		return JSON.toJSONString(result);
	}

	public String cardDetail(String cardId) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		String result = cardService.getCardDetail(cardId, getAccessToken(configBean.getAppid(), configBean.getAppsecret()));
		return JSON.toJSONString(Result.ok(result));
	}
	
	public String cardDelete(String cardId) throws Exception{
		BaseConfigBean configBean = getBaseConfig();
		cardService.cardDelete(cardId, getAccessToken(configBean.getAppid(), configBean.getAppsecret()));
		return JSON.toJSONString(Result.ok());
	}
	
	/**
	 * 微信反人类接口，JSON对象用双引号引着
	 * @param pageNum
	 * @param pageSize
	 * @param group
	 * @return
	 * @throws Exception
	 */
	public String pois(Integer pageNum, Integer pageSize, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		String accessToken = getAccessToken(configBean.getAppid(), configBean.getAppsecret());
		Map<String,String> param = new HashMap<String,String>();
		param.put("access_token", accessToken);
		param.put("page", String.valueOf(pageNum));
		param.put("page_rows", String.valueOf(pageSize));
		String res = RequestUtils.get("https://api.weixin.qq.com/wxa/getnearbypoilist",param).string();
		res = jsonFilter(res);
		GetnearbypoilistResult pois = JSON.parseObject(res, GetnearbypoilistResult.class);
		List<GetnearbypoilistPoi> poiList = null;
		if(pois != null && pois.getData() != null && pois.getData().getData() != null && pois.getData().getData().getPoi_list() != null) {
			poiList = pois.getData().getData().getPoi_list();
		}
		Integer leftApplNum = pois!=null&&pois.getData()!=null&&pois.getData().getLeft_apply_num()!=null?pois.getData().getLeft_apply_num():0;
		Integer maxApplyNum = pois!=null&&pois.getData()!=null&&pois.getData().getMax_apply_num()!=null?pois.getData().getMax_apply_num():10;
		return JSON.toJSONString(Result.ok().addData("poi_list", poiList==null?Collections.emptyList():poiList)
				.addData("left_apply_num", leftApplNum)
				.addData("max_apply_num", maxApplyNum));
	}
	
	private String jsonFilter(String str) {
		
		return str.replaceAll("data\":\"", "data\":").replaceAll("}}]}\"", "}}]}").replaceAll("}\"", "}").replaceAll("\\\\", "");
	}
	
	public String deleteNearbyPoi(String poiId, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		BaseResult result = WxaAPI.delnearbypoi(getAccessToken(configBean.getAppid(), configBean.getAppsecret()), poiId);
		if(result.getErrmsg().equals("ok")) {
			return JSON.toJSONString(Result.ok());
		}
		return JSON.toJSONString(Result.error(result.getErrmsg()));
	}

	public String nearByshowStatus(String poiId, Integer status, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		BaseResult baseResult = WxaAPI.setnearbypoishowstatus(getAccessToken(configBean.getAppid(), configBean.getAppsecret()), poiId, status);
		if(baseResult.getErrmsg().equals("ok")) {
			return JSON.toJSONString(Result.ok());
		}
		return JSON.toJSONString(Result.error(baseResult.getErrmsg()));
	}

	public String addNearByPoi(String data) throws Exception{
		JSONObject jsonObject = JSON.parseObject(data);
		BaseConfigBean configBean = getBaseConfig(jsonObject.getString("group"));
		Addnearbypoi addnearbypoi = JSON.parseObject(data, Addnearbypoi.class);
		AddnearbypoiResult result = WxaAPI.addnearbypoi(getAccessToken(configBean.getAppid(), configBean.getAppsecret()), addnearbypoi);
		return JSON.toJSONString(Result.ok(result.getData()));
	}
	
	
	public String payNotify(String data) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		BaseConfigBean configBean = getBaseConfig();
		return payService.payNotify(data, wxPayConfig, configBean);
	}

	public String refundNotify(String data) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		BaseConfigBean configBean = getBaseConfig();
		return payService.refundNotify(data, wxPayConfig, configBean);
	}
	
	public String unifiedOrder(String orderData) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		return payService.unifiedOrder(orderData, wxPayConfig);
	}

	public String refund(String refundData) throws Exception{
		String appid = JSONObject.parseObject(refundData).getString("appid");
		WxPayConfig wxPayConfig = null;
		if(StringUtils.isNotEmpty(appid)) {//传入了appid则根据appid直接查询配置
			wxPayConfig = getPayConfigByAppid(appid);
		}else {//否则按照其他逻辑查询配置
			wxPayConfig = getPayConfig(true);
		}
		return payService.refund(wxPayConfig, refundData);
	}

	public String refundQuery(String outTradeNo, String transactionId, String outRefundNo, String refundId) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		if("-1".equals(outTradeNo)) outTradeNo = "";
		if("-1".equals(transactionId)) transactionId = "";
		if("-1".equals(outRefundNo)) outRefundNo = "";
		if("-1".equals(refundId)) refundId = "";
		return payService.refundQuery(wxPayConfig, transactionId, outTradeNo, outRefundNo, refundId);
	}

	public String closeOrder(String outTradeNo) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		return payService.orderClose(wxPayConfig, outTradeNo);
	}

	public String queryEntPay(String partnerTradeNo) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		return payService.queryEntPay(wxPayConfig, partnerTradeNo);
	}

	public String downloadBill(String billDate, String billType, String tarType, String deviceInfo) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		if("-1".equals(deviceInfo)) deviceInfo = "";
		return payService.dowloadBill(wxPayConfig, billDate, billType, tarType, deviceInfo);
	}

	public String entPay(String data) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(true);
		wxPayConfig.setNotifyUrl(host()+Constants.MINIAPP_DEFUALT_NOFITY_HOST);
		return payService.entPay(wxPayConfig, data);
	}

	public String entPayBank(String data) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(true);
		wxPayConfig.setNotifyUrl(host()+Constants.MINIAPP_DEFUALT_NOFITY_HOST);
		return payService.payBank(wxPayConfig, data);
	}

	public String queryEntPayBank(String partnerTradeNo) throws Exception{
		WxPayConfig wxPayConfig = getPayConfig(false);
		return payService.queryEntPay(wxPayConfig, partnerTradeNo);
	}

	public String queryOrder(String outTradeNo, String transactionId) throws Exception{
		if("-1".equals(outTradeNo)) outTradeNo = "";
		if("-1".equals(transactionId)) transactionId = "";
		WxPayConfig wxPayConfig = getPayConfig(false);
		return payService.orderQuery(wxPayConfig, outTradeNo, transactionId);
	}

	public String getTempMaterial(String mediaId, String group) throws Exception{
		BaseConfigBean configBean = getBaseConfig(group);
		String accessToken = getAccessToken(configBean.getAppid(), configBean.getAppsecret());
		return materialService.getTempMaterial(mediaId, accessToken);
	}

	public String addTempMaterial(MaterialVo materialVo) throws Exception{
		BaseConfigBean configBean = getBaseConfig(materialVo.getGroup());
		String accessToken = getAccessToken(configBean.getAppid(), configBean.getAppsecret());
		return materialService.addTempMaterial(materialVo, accessToken);
	}
	
	public String decryptData(String encryptedData, String iv) throws Exception{
		String sessionKey = getHeader("X-Session-SessionKey");
		logger.info("sessionKey={}",sessionKey);
		return WxMaCryptUtils.decrypt(sessionKey, encryptedData, iv);
	}
	
	
}

